import sys
from web3 import Web3, HTTPProvider
from web3.eth import Eth

w3 = Web3(HTTPProvider('http://localhost:8545')) #初始化区块链节点连接
eth = Eth(w3)
accounts = w3.eth.accounts #获取本地区块链所有账户

#定义一个16进制字符串格式化输出函数
def bytesToHexString(bs):
   return ''.join(['%02x' % b for b in bs])

def saveDataOnBlock(data):
    #检查是否连接成功
    if w3.eth.getBlock(0) is None:
	    print("Blockchain connect failed！")   
    elif w3.isConnected():
	    print("Blockchain connected successfully！")
        
    #读取账户余额
    balance = w3.eth.getBalance(accounts[0],'latest')
    print('balance before tx => {0}'.format(balance))

    data_into_block=Web3.toHex(text=data) 
    #设置交易，从节点第1个账户向第2个账户转500wei
    payload = {
    'from': accounts[0],
    'to': accounts[1],
    'value': 500,
    'data':data_into_block
    }
    #向以太坊节点提交交易，**节点将返回该交易的哈希值**
    tx_hash = w3.eth.sendTransaction(payload)
    print('tx hash => {0}'.format(Web3.toHex(tx_hash)))

    #发送完交易之后必须进行挖矿才能真正完成以太发送，其实就把以太坊当成账本，任何变动都需要记账，“记账的实现方式就是挖矿”。
    w3.geth.miner.start(2) #开始启用两个CPU内核进行挖矿，因为是在本地测试链上，所以速度很快。
    w3.geth.miner.stop() #停止挖矿，同时通过挖矿实现数据上链。

    #读取交易后的账户余额（Ganache是实时完成交易的，所以这个可以立刻看到交易完成，余额发生变化）
    balance = w3.eth.getBalance(accounts[0],'latest')
    print('balance after tx => {0}'.format(balance))

    trans_result=w3.eth.get_transaction(tx_hash)
    print('Block Hash:',bytesToHexString(trans_result['blockHash']))
    print('Block Number:',trans_result['blockNumber'])
    print('Transaction Index:',trans_result['transactionIndex'])
    print('Input Data:',w3.toText(trans_result['input'])) #显示刚存储上链的原始数据信息

    count=0
    block_num=w3.eth.getBlock('latest').number #获取最新的区块号
    for i in range(block_num):     
        try:
            blockn=w3.eth.getBlock(i) #获取指定区块的信息
            print("Block",str(i)," hash:",bytesToHexString(blockn.hash))
            count+=1              
        except:
            print('No more blocks in current blockchain.') 
            break
    print('\n{0} blocks in current blockchain.'.format(count)) 

if __name__=="__main__":
    if(len(sys.argv)!=3):
         print("Wrong parameters! Usage Example: python saveDataOnBlock.py -d 'Sample Data'") 
         exit(0) 
    data=sys.argv[2]     
    saveDataOnBlock(data)
